import numpy as np
import cv2 as cv
import os
import time

#调用图片识别服务
class cvCNNImage:
    __instance=None
    __init_flag=False
    def __new__(cls):
        if cls.__instance==None:
            cls.__instance=object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance
    def __init__(self):
        if self.__init_flag==False:
            yolo_dir = 'D:/opencvyolo/opencvyolo'  # YOLO文件路径
            weightsPath = os.path.join(yolo_dir, 'yolov3.weights')  # 权重文件
            configPath = os.path.join(yolo_dir, 'yolov3.cfg')  # 配置文件
            self.labelsPath = os.path.join(yolo_dir, 'coco.names')  # label名称
            # imgPath = os.path.join(yolo_dir, 'dog.jpg')  # 测试图像
            self.CONFIDENCE = 0.5  # 过滤弱检测的最小概率
            self.THRESHOLD = 0.4  # 非最大值抑制阈值
            self.net = cv.dnn.readNetFromDarknet(configPath,weightsPath)
        else:
            pass
    #得到识别结果
    def getRegResult(self):
        return self.ayy
    def testClsId(self):
        print("cvCNNImage id:%s"%(id(self)),flush=True)

    def __call__(self, img):
        blobImg = cv.dnn.blobFromImage(img,1.0/255,(416,416),None,True,False)
        self.net.setInput(blobImg)

        outInfo = self.net.getUnconnectedOutLayersNames()
        start = time.time()

        layerOutputs = self.net.forward(outInfo)
        end = time.time()

        print("[INFO] YOLO took {:0.6f} seconds".format(end - start))

        (H,W) = img.shape[:2]

        boxes = []
        confidences = []
        classIDs = []

        for out in layerOutputs:
            for detection in out:
                scores = detection[5:]
                classID = np.argmax(scores)
                confidence = scores[classID]
                if confidence > self.CONFIDENCE:
                    box = detection[0:4]*np.array([W,H,W,H])
                    (centerX,centerY,width,height) = box.astype("int")
                    x = int(centerX - (width)/2)
                    y = int(centerY - (height)/2)

                    boxes.append([x,y,int(width),int(height)])

                    confidences.append(float(confidence))
                    classIDs.append(classID)

        idxs = cv.dnn.NMSBoxes(boxes,confidences,self.CONFIDENCE,self.THRESHOLD)

        with open(self.labelsPath,'rt') as f:
            labels = f.read().rstrip('\n').split('\n')


        np.random.seed(42)
        COLORS = np.random.randint(0,255,size = (len(labels),3),dtype = "uint8")
        #返回的值
        self.ayy=[]
        if len(idxs) > 0:
            for i in idxs.flatten():
                dict = {} #对象的概念
                (x,y) = (boxes[i][0],boxes[i][1])
                (w,h) = (boxes[i][2],boxes[i][3])
                color = [int(c) for c in COLORS[classIDs[i]]]
                cv.rectangle(img,(x,y),(x +w ,y+h),color,2)
                #开始位置及其长度
                dict["x"]=x
                dict["y"]=y
                dict["w"]=w
                dict["h"]=h
                text="{}: {:.4f},    ".format(labels[classIDs[i]], confidences[i])
                dict["who"]=labels[classIDs[i]]
                dict["confidence"]=confidences[i]
                self.ayy.append(dict) #添加到数组
                cv.putText(img, text, (x, y - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
            # cv.FONT_HERSHEY_SIMPLEX字体风格、0.5字体大小、粗细2px
            # cv.imwrite(imgPath,img) #不再显示图片
        return self.ayy
    # cv.imshow('detected image', img)
    # cv.waitKey(0)





















